package form.ui.component.ScrollBar
{
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	
	import form.events.ScrollBarEvent;
	import form.ui.core.FMSprite;
	import form.utils.MathUtils;

	public class ScrollBar extends FMSprite {
		private const MIN_SCROLL_HEIGHT:uint = 10;
		
		protected var handle:Handle;
		protected var screen:Screen = new Screen();
		
		private var currentStage:Stage;
		
		public function ScrollBar() {
			super();
			
			this.handle = new Handle(this);
			
			this.mouseEnabled = true;
			this.buttonMode = true;
			this.useHandCursor = true;
			
			this.fillColor = 0xcccccc;
			this.fillOpacity = 1;
			
			this.addChild(this.handle);
			
			this.width = this.handle.width;
			
			this.addEventListener(MouseEvent.MOUSE_DOWN, this.onMouseDown);
			
			this.addEventListener(Event.ADDED_TO_STAGE, this.onAddedToStage);
			this.addEventListener(Event.REMOVED_FROM_STAGE, this.onRemovedFromStage);
		}
		
		public function get dragging():Boolean { return this.handle.dragging; }
		
		public function set handleHeight(value:Number):void {
			MathUtils.constrain(value, 0, 1);
			var synchronizeHeight:Number = value * this.height;
			this.handle.synchronizeHeight = Math.max(synchronizeHeight, MIN_SCROLL_HEIGHT);
		}
		
		public function set handleValue(value:Number):void {
			value = MathUtils.constrain(value, 0, 1);
			
			this.handle.y = (this.height - this.handle.height) * value;
		}
		
		public function get handleValue():Number {
			return this.handle.y / (this.height - this.handle.height);
		}
		
		protected function get bounds():Rectangle {
			var bounds:Rectangle = new Rectangle();
			bounds.x = 0;
			bounds.y = 0;
			bounds.width = 0;
			bounds.height = this.height - this.handle.height;
			return bounds;
		}
		
		protected function onMouseDown(event:MouseEvent):void {
			this.handle.y = MathUtils.constrain(this.mouseY - this.handle.height / 2, this.bounds.y, bounds.height);
			
			var e:ScrollBarEvent = new ScrollBarEvent(ScrollBarEvent.SCROLLED);
			e.value = this.handleValue;
			
			this.dispatchEvent(e);
			
			this.handle.startDrag(false, this.bounds);
			
			this.currentStage.addChild(this.screen);
		}
		
		protected function onMouseUp(e:MouseEvent):void {
			if (this.handle.dragging) { this.handle.stopDrag(); }
		}
		
		protected function onAddedToStage(e:Event):void {
			this.currentStage = this.stage;
			
			this.currentStage.addEventListener(MouseEvent.MOUSE_UP, this.onMouseUp);
		}
		
		protected function onRemovedFromStage(e:Event):void {
			this.currentStage.removeEventListener(MouseEvent.MOUSE_UP, this.onMouseUp);
			this.currentStage = null;	
		}
		
		public function set handleUpSkin(value:String):void
		{
			handle.upSkin = value;
		}
		
		public function set handleOverSkin(value:String):void
		{
			handle.overSkin = value;
		}
		
		public function set handleDownSkin(value:String):void
		{
			handle.downSkin = value;
		}
		
		public function set handleDisableSkin(value:String):void
		{
			handle.disabledSkin = value;
		}
	}
}